﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

using SMBL.Global;
using SMBL.Core;
using SMBL.ConfigElement.DBProvider;
using SMBL.Interface.Database;

namespace SMBL
{
    namespace ADBS
    {
        /// <summary>
        /// Connection Control Unit
        /// @Author: Push
        /// </summary>
        public class ConnectionControl : Interface.AbstractServer.IAS
        {
            //////////////////////////////////////////////////////////////////////////
            // Global Parameters
            //////////////////////////////////////////////////////////////////////////
            private static Hashtable myConnectionPoolMap = new Hashtable();
            
            private static ConnectionControl myCCL = null;

            /// <summary>
            /// Private Construction
            /// This class cannot be instanced.
            /// @Author: Push
            /// </summary>
            private ConnectionControl() { }

            static public SMBL.Interface.AbstractServer.IAS SingletonInstance()
            {
                // throw new NotImplementedException();
                if (myCCL == null) myCCL = new ConnectionControl();
                return myCCL;
            }

            //////////////////////////////////////////////////////////////////

            #region IAS Members

            public SMBL.Interface.AbstractServer.IAProvider GetProvider(string BindString)
            {
                //throw new NotImplementedException();
                if ( BindString == null) throw new NullReferenceException();
                // Invoke the bind connection pool's get connection method
                return ((ConnectionPool)myConnectionPoolMap[BindString]).GetConnection();
            }

            public bool ReleaseProvider(string BindString, ref SMBL.Interface.AbstractServer.IAProvider theProvider)
            {
                //throw new NotImplementedException();
                if (BindString == null) throw new NullReferenceException();
                // Invoke the bind connection pool's release connection method
                //IDBProvider p = (IDBProvider)theProvider;
                ((ConnectionPool)myConnectionPoolMap[BindString]).ReleaseConnection((IDBProvider)theProvider);
                return true;
            }

            private Boolean _isStarted = false;
            public bool IsStarted
            {
                //throw new NotImplementedException();
                //return _isStarted;
                get { return _isStarted; }
            }

            private Boolean _beLocked = true;
            public bool IsAvailable
            {
                //throw new NotImplementedException();
                //return (!_beLocked);
                get { return !_beLocked; }
            }

            #endregion

            #region IStart Members

            public bool Start()
            {
                //throw new NotImplementedException();
                if (_isStarted) return _isStarted;
                // Get all names of the Providers
                Hashtable tmpProviderList = Kernel.GetInstance().ProviderInfoList;
                ArrayList tmpProviderNames = new ArrayList(tmpProviderList.Keys);
                // Create connection pool instances
                for (int i = tmpProviderList.Count - 1; i >= 0; --i)
                {
                    ConnectionPool connPool = new ConnectionPool((DBProviderInfo)tmpProviderList[tmpProviderNames[i]]);
                    connPool.Start();
                    myConnectionPoolMap.Add(tmpProviderNames[i], connPool);
                }
                _isStarted = true;
                _beLocked = false;
                return true;
            }

            #endregion

            #region IRestart Members

            public bool Restart()
            {
                //throw new NotImplementedException();
                if (_beLocked) return false;
                _beLocked = true;
                // End it.
                this.End();
                // Start it.
                this.Start();
                _beLocked = false;
                return true;
            }

            #endregion

            #region IEnd Members

            public bool End()
            {
                //throw new NotImplementedException();
                if (!_isStarted) return true;
                // Get all names of the Providers
                ArrayList tmpProviderNames = new ArrayList(myConnectionPoolMap.Keys);
                // End all connection pool
                _isStarted = false;
                for (int i = tmpProviderNames.Count - 1; i >= 0; --i)
                {
                    ((ConnectionPool)myConnectionPoolMap[tmpProviderNames[i]]).End();
                }

                myConnectionPoolMap.Clear();
                myConnectionPoolMap = null;

                return true;
            }

            #endregion
        }
    }
}